home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume24 / gnudiff1.15 / part04 < prev    next >
Encoding:
Internet Message Format  |  1991-03-05  |  39.5 KB

  1. Subject:  v24i019:  GNU Diff, version 1.15, Part04/08
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: 1d057d0c efd6dcc4 af15a11f 83ae731f
  5.  
  6. Submitted-by: Paul Eggert <eggert@twinsun.com>
  7. Posting-number: Volume 24, Issue 19
  8. Archive-name: gnudiff1.15/part04
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 4 (of 8)."
  17. # Contents:  ChangeLog io.c
  18. # Wrapped by eggert@ata on Mon Jan  7 11:25:30 1991
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. if test -f 'ChangeLog' -a "${1}" != "-c" ; then 
  21.   echo shar: Will not clobber existing file \"'ChangeLog'\"
  22. else
  23. echo shar: Extracting \"'ChangeLog'\" \(19300 characters\)
  24. sed "s/^X//" >'ChangeLog' <<'END_OF_FILE'
  25. XSun Jan  6 18:42:23 1991  Michael I Bushnell  (mib at geech.ai.mit.edu)
  26. X
  27. X    * Version 1.15 released.
  28. X
  29. X    * version.c: Updated from 1.15 alpha to 1.15
  30. X
  31. X    * context.c (print_context_number_range,
  32. X    print_unidiff_number_range): Don't print N,M when N=M, print
  33. X    just N instead.
  34. X    
  35. X    * README: Updated for version 1.15.
  36. X    Makefile: Updated for version 1.15.
  37. X
  38. X    * diff3.c (main): Don't get confused if one of the arguments
  39. X    is a directory.
  40. X
  41. X    * diff.c (compare_files): Don't get confused if comparing
  42. X    standard input to a directory; print error instead.
  43. X
  44. X    * analyze.c (diff_2_files), context.c (print_context_header,
  45. X    print_context_script), diff.c (main), diff.h (enum
  46. X    output_style): Tread unidiff as an output style in its own
  47. X    right.  This also generates an error when both -u and -c are
  48. X    given.
  49. X
  50. X    * diff.c (main): Better error messages when regexps are bad.
  51. X
  52. X    * diff.c (compare_files): Don't assume stdin is opened.
  53. X
  54. X    * diff3.c (read_diff): Don't assume things about the order of
  55. X    descriptor assignment and closes.
  56. X
  57. X    * util.c (setup_output): Don't assume things about the order
  58. X    of descriptor assignment and closes. 
  59. X
  60. X    * diff.c (compare_files): Set a flag so that closes don't
  61. X    happen more than once.
  62. X
  63. X    * diff.c (main): Don't just flush stdout, do a close.  That
  64. X    way on broken systems we can still get errors. 
  65. X
  66. XMon Dec 24 16:24:17 1990  Richard Stallman  (rms at mole.ai.mit.edu)
  67. X
  68. X    * diff.c (usage): Use = for args of long options.
  69. X
  70. XMon Dec 17 18:19:20 1990  Michael I Bushnell  (mib at geech.ai.mit.edu)
  71. X
  72. X    * context.c (print_context_label): Labels were interchanged badly.
  73. X
  74. X    * context.c (pr_unidiff_hunk): Changes to deal with files
  75. X    ending in incomplete lines.
  76. X    * util.c (print_1_line): Other half of the changes.
  77. X
  78. XMon Dec  3 14:23:55 1990  Richard Stallman  (rms at mole.ai.mit.edu)
  79. X
  80. X    * diff.c (longopts, usage): unidiff => unified.
  81. X
  82. XWed Nov  7 17:13:08 1990  Richard Stallman  (rms at mole.ai.mit.edu)
  83. X
  84. X    * analyze.c (diff_2_files): No warnings about newlines for -D.
  85. X
  86. X    * diff.c (pr_unidiff_hunk): Remove ref to output_patch_flag.
  87. X
  88. XTue Oct 23 23:19:18 1990  Richard Stallman  (rms at mole.ai.mit.edu)
  89. X
  90. X    * diff.c (compare_files): For -D, compare even args are same file.
  91. X    * analyze.c (diff_2_files): Likewise.
  92. X    Also, output even if files have no differences.
  93. X
  94. X    * analyze.c (diff_2_files): Print missing newline messages last.
  95. X    Return 2 if a newline is missing.
  96. X    Print them even if files end with identical text.
  97. X
  98. XMon Oct 22 19:40:09 1990  Richard Stallman  (rms at mole.ai.mit.edu)
  99. X
  100. X    * diff.c (usage): Return 2.
  101. X
  102. XWed Oct 10 20:54:04 1990  Richard Stallman  (rms at mole.ai.mit.edu)
  103. X
  104. X    * diff.c (longopts): Add +new-files.
  105. X
  106. XSun Sep 23 22:49:29 1990  Richard Stallman  (rms at mole.ai.mit.edu)
  107. X
  108. X    * context.c (print_context_script): Handle unidiff_flag.
  109. X    (print_context_header): Likewise.
  110. X    (print_unidiff_number_range, pr_unidiff_hunk): New functions.
  111. X    * diff.c (longopts): Add element for +unidiff.
  112. X    (main): Handle +unidiff and -u.
  113. X    (usage): Mention them.
  114. X
  115. XWed Sep  5 16:33:22 1990  Richard Stallman  (rms at mole.ai.mit.edu)
  116. X
  117. X    * io.c (find_and_hash_each_line): Deal with missing final newline
  118. X    after buffering necessary context lines.
  119. X
  120. XSat Sep  1 16:32:32 1990  Richard Stallman  (rms at mole.ai.mit.edu)
  121. X
  122. X    * io.c (find_identical_ends): ROBUST_OUTPUT_FORMAT test was backward.
  123. X
  124. XThu Aug 23 17:17:20 1990  Richard Stallman  (rms at mole.ai.mit.edu)
  125. X
  126. X    * diff3.c (WIFEXITED): Undef it if WEXITSTATUS is not defined.
  127. X    * context.c (find_function): Don't try to return values.
  128. X
  129. XWed Aug 22 11:54:39 1990  Richard Stallman  (rms at mole.ai.mit.edu)
  130. X
  131. X    * diff.h (O_RDONLY): Define if not defined.
  132. X
  133. XTue Aug 21 13:49:26 1990  Richard Stallman  (rms at mole.ai.mit.edu)
  134. X
  135. X    * Handle -L option.
  136. X    * context.c (print_context_label): New function.
  137. X    (print_context_header): Use that.
  138. X    * diff.c (main): Recognize the option.
  139. X    (usage): Updated.
  140. X    * diff.h (file_label): New variable.
  141. X    * diff3.c (main): Recognize -L instead of -t.
  142. X
  143. X    * diff3.c (main): Support -m without other option.
  144. X
  145. X    * diff3.c (WEXITSTATUS, WIFEXITED): Define whenever not defined.
  146. X
  147. X    * diff3.c (bcopy, index, rindex): Delete definitions; not used.
  148. X    (D_LINENUM, D_LINELEN): Likewise.
  149. X    (struct diff_block): lengths includes newlines.
  150. X    (struct diff3_block): Likewise.
  151. X    (always_text, merge): New variables.
  152. X    (read_diff): Return address of end, not size read.  Calls changed.
  153. X    Pass -a to diff if given to diff3.
  154. X    current_chunk_size now an int.  Detect error in `pipe'.
  155. X    Check for incomplete line of output here.
  156. X    (scan_diff_line): Don't make scan_ptr + 2 before knowing it is valid.
  157. X    No need to check validity of diff output here.
  158. X    Include newline in length of line.
  159. X    (main): Compute rev_mapping here.  Handle -a and -m.
  160. X    Error message if excess -t operands.  Error for incompatible options.
  161. X    Error if `-' given more than once.
  162. X    Fix error storing in tag_strings.
  163. X    (output_diff3): REV_MAPPING is now an arg.  Call changed.
  164. X    Change syntax of "missing newline" message.
  165. X    Expect length of line to include newline.
  166. X    (output_diff3_edscript): Return just 0 or 1.
  167. X    REV_MAPPING is now an arg.  Call changed.
  168. X    (output_diff3_merge): New function.
  169. X    (process_diff): Better error message for bad diff format.
  170. X    (fatal, perror_with_exit): Return status 2.
  171. X
  172. X    * analyze.c (diff_2_files): Report missing newline in either
  173. X    or both files, if not robust output style.
  174. X
  175. X    * util.c (setup_output): Detect error from pipe.
  176. X    No need to close stdin.
  177. X
  178. X    * util.c (print_1_line): Change format of missing-newline msg.
  179. X    Change if statements to switch.
  180. X
  181. X    * io.c (slurp): Don't mention differences in final newline if -B.
  182. X
  183. X    * io.c (binary_file_p): Use ISO char set as criterion, not ASCII.
  184. X
  185. X    * io.c (find_identical_ends): Increase value of BEG0 by 1.
  186. X    Other changes in backwards scan to avoid decrementing pointers
  187. X    before start of array, and set LINES properly.
  188. X
  189. X    * diff.h (ROBUST_OUTPUT_STYLE): New macro.
  190. X    * io.c (find_identical_ends, find_and_hash_each_line): Use that macro.
  191. X
  192. X    * diff.h (dup2): Don't define if XENIX.
  193. X
  194. X    * diff.c (main): Check for write error at end.
  195. X
  196. X    * context.c (find_function): Don't return a value.
  197. X    Use argument FILE rather than global files.
  198. X
  199. X    * analyze.c: Add external function declarations.
  200. X    * analyze.c (build_script): Turn off explicit check for final newline.
  201. X
  202. X    * analyze.c (discard_confusing_lines): Make integers unsigned.
  203. X
  204. XTue Jul 31 21:37:16 1990  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  205. X
  206. X    * io.c (find_and_hash_each_line): Correct the criterion 
  207. X    for leaving out the newline from the end of the line.
  208. X
  209. XTue May 29 21:28:16 1990  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  210. X
  211. X    * dir.c (diff_dirs): Free things only if nonzero.
  212. X
  213. XMon Apr 16 18:31:05 1990  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  214. X
  215. X    * diff.h (NDIR_IN_SYS): New macro controls location of ndir.h.
  216. X
  217. X    * diff3.c (xmalloc, xrealloc): Don't die if size == 0 returns 0.
  218. X
  219. XSun Mar 25 15:58:42 1990  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  220. X
  221. X    * analyze.c (discard_confusing_lines):
  222. X    `many' wasn't being used; use it.
  223. X    Cancelling provisionals near start of run must handle already
  224. X    cancelled provisionals.
  225. X    Cancelling subruns of provisionals was cancelling last nonprovisional.
  226. X
  227. XSat Mar 24 14:02:51 1990  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  228. X
  229. X    * analyze.c (discard_confusing_lines):
  230. X    Threshold for line occurring many times scales by square root
  231. X    of total lines.
  232. X    Within each run, cancel any long subrun of provisionals.
  233. X    Don't update `provisional' while cancelling provisionals.
  234. X    In big outer loop, handle provisional and nonprovisional separately.
  235. X
  236. XThu Mar 22 16:35:33 1990  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  237. X
  238. X    * analyze.c (discard_confusing_lines):
  239. X    The first loops to discard provisionals from ends failed to step.
  240. X    In second such loops, keep discarding all consecutive provisionals.
  241. X    Increase threshold for stopping discarding, and also check for
  242. X    consecutive nondiscardables as separate threshold.
  243. X
  244. XFri Mar 16 00:33:08 1990  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  245. X
  246. X    * diff3.c (read_diff): Pass -- as first arg to diff.
  247. X
  248. X    * diff3.c: Include wait.h or define equivalent macros.
  249. X    (read_diff): Don't use stdio printing error in the inferior.
  250. X    Remember the pid and wait for it.  Report failing status.
  251. X    Report failure of vfork.
  252. X
  253. XSun Mar 11 17:10:32 1990  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  254. X
  255. X    * diff3.c (main): Accept -t options and pass to output_diff3_edscript.
  256. X    (usage): Mention -t.
  257. X    (read_diff): Use vfork.
  258. X    (vfork): Don't use it on Sparc.
  259. X
  260. X    * diff.h (vfork): Don't use it on Sparc.
  261. X
  262. XTue Mar  6 22:37:20 1990  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  263. X
  264. X    * diff3.c (dup2): Don't define on Xenix.
  265. X
  266. X    * Makefile: Comments for Xenix.
  267. X
  268. XThu Mar  1 17:19:23 1990  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  269. X
  270. X    * analyze.c (diff_2_files): `message' requires three args.
  271. X
  272. XFri Feb 23 10:56:50 1990  David J. MacKenzie  (djm at albert.ai.mit.edu)
  273. X
  274. X    * diff.h, util.c, diff3.c: Change 'void *' to 'VOID *', with
  275. X    VOID defined as void if __STDC__, char if not.
  276. X
  277. XSun Feb 18 20:31:58 1990  David J. MacKenzie  (djm at albert.ai.mit.edu)
  278. X
  279. X    * Makefile: Add rules for getopt.c, getopt1.c, getopt.h.
  280. X
  281. X    * getopt.c, getopt.h, getopt1.c: New files.
  282. X
  283. X    * main.c (main, usage): Add long options.
  284. X
  285. X    * analyze.c (shift_boundaries): Remove unused var 'j_end'.
  286. X
  287. XThu Feb  8 02:43:16 1990  Jim Kingdon  (kingdon at pogo.ai.mit.edu)
  288. X
  289. X    * GNUmakefile: include ../Makerules before Makefile.
  290. X
  291. XFri Feb  2 23:21:38 1990  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  292. X
  293. X    * analyze.c (diif_2_files): If -B or -I, don't return 1
  294. X    if all changes were ignored.
  295. X
  296. XWed Jan 24 20:43:57 1990  Richard Stallman  (rms at albert.ai.mit.edu)
  297. X
  298. X    * diff3.c (fatal): Output to stderr.
  299. X
  300. XThu Jan 11 00:25:56 1990  David J. MacKenzie  (djm at hobbes.ai.mit.edu)
  301. X
  302. X    * diff.c (usage): Mention -v.
  303. X
  304. XWed Jan 10 16:06:38 1990  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  305. X
  306. X    * diff3.c (output_diff3_edscript): Return number of overlaps.
  307. X    (main): If have overlaps, exit with status 1.
  308. X
  309. XSun Dec 24 10:29:20 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  310. X
  311. X    * io.c (find_equiv_class): Fix typo that came from changing init of B
  312. X    to an assigment.
  313. X
  314. X    * version.c: New file.
  315. X    * diff.c (main): -v prints version number.
  316. X
  317. X    * io.c (binary_file_p): Null char implies binary file.
  318. X
  319. XFri Nov 17 23:44:55 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  320. X
  321. X    * util.c (print_1_line): Fix off by 1 error.
  322. X
  323. XThu Nov 16 13:51:10 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  324. X
  325. X    * util.c (xcalloc): Function deleted.
  326. X
  327. X    * io.c (slurp): Null-terminate the buffer.
  328. X
  329. X    * io.c (read_files): Delete unused vars.
  330. X
  331. X    * io.c (find_equiv_class): Don't index by N if too low.
  332. X
  333. X    * dir.c (dir_sort): Delete the extra declaration of compare_names.
  334. X
  335. X    * diff.h: Don't declare xcalloc.  Declare some other functions.
  336. X
  337. X    * analyze.c (shift_boundaries):
  338. X    Test for END at end of range before indexing by it.
  339. X    Fix typo `preceeding' in var names.
  340. X
  341. XSat Nov 11 14:04:16 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  342. X
  343. X    * diff3.c (using_to_diff3_block): Delete unused vars.
  344. X    (make_3way_diff, process_diff_control, read_diff, output_diff3): Likewise.
  345. X
  346. XMon Nov  6 18:15:50 EST 1989 Jay Fenlason (hack@ai.mit.edu)
  347. X
  348. X    * README Fix typo.
  349. X
  350. XFri Nov  3 15:27:47 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  351. X
  352. X    * diff.c (usage): Mention -D. 
  353. X
  354. X    * ifdef.c (print_ifdef_hunk): Write comments on #else and #endif.
  355. X
  356. XSun Oct 29 16:41:07 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  357. X
  358. X    * diff.c (compare_files): Don't fflush for identical files.
  359. X
  360. XWed Oct 25 17:57:12 1989  Randy Smith  (randy at apple-gunkies.ai.mit.edu)
  361. X
  362. X    * diff3.c (using_to_diff3_block): When defaulting lines from
  363. X    FILE0, only copy up to just under the *lowest* line mentioned
  364. X    in the next diff.
  365. X
  366. X    * diff3.c (fatal): Add \n to error messages.
  367. X
  368. XWed Oct 25 15:05:49 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  369. X
  370. X    * Makefile (tapefiles): Add ChangeLog.
  371. X
  372. XTue Oct  3 00:51:17 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  373. X
  374. X    * diff3.c (process_diff, create_diff3_block): Init ->next field.
  375. X
  376. XFri Sep 29 08:16:45 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  377. X
  378. X    * util.c (line_cmp): Alter end char of line 2, not line 1.
  379. X
  380. XWed Sep 20 00:12:37 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  381. X
  382. X    * Makefile (diff.tar): Expect ln to fail on some files;
  383. X    copy them with cp.
  384. X
  385. XMon Sep 18 02:54:29 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  386. X
  387. X    * Handle -D option:
  388. X    * io.c (find_and_hash_each_line): Keep all lines of 1st file.
  389. X    * diff.c (main): Handle -D option.
  390. X    (compare_files): Reject -D if files spec'd are directories.
  391. X    * analyze.c (diff_2_files): Handle OUTPUT_IFDEF case.
  392. X
  393. XFri Sep  1 20:15:50 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  394. X
  395. X    * diff.c (option_list): Rename arg VECTOR as OPTIONVEC.
  396. X
  397. XMon Aug 28 17:58:27 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  398. X
  399. X    * diff.c (compare_files): Clear entire inf[i].stat.
  400. X
  401. XWed Aug 23 17:48:47 1989  Richard Stallman  (rms at apple-gunkies.ai.mit.edu)
  402. X
  403. X    * io.c (find_identical_ends): Sign was backward
  404. X    determining where to bound the scan for the suffix.
  405. X
  406. XWed Aug 16 12:49:16 1989  Richard Stallman  (rms at hobbes.ai.mit.edu)
  407. X
  408. X    * analyze.c (diff_2_files): If -q, treat all files as binary.
  409. X    * diff.c (main): Detect -q, record in no_details_flag.
  410. X
  411. XSun Jul 30 23:12:00 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  412. X
  413. X    * diff.c (usage): New function.
  414. X    (main): Call it.
  415. X
  416. XWed Jul 26 02:02:19 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  417. X
  418. X    * diff.c (main): Make -C imply -c.
  419. X
  420. XThu Jul 20 17:57:51 1989  Chris Hanson  (cph at kleph)
  421. X
  422. X    * io.c (find_and_hash_each_line): Bug fix in context handling,
  423. X    introduced by last change.
  424. X
  425. XFri Jul 14 17:39:20 1989  Chris Hanson  (cph at kleph)
  426. X
  427. X    * analyze.c: To make RCS work correctly on files that don't
  428. X    necessarily end in newline, introduce some changes that cause
  429. X    diffs to be sensitive to missing final newline.  Because
  430. X    non-RCS modes don't want to be affected by these changes, they
  431. X    are conditional on `output_style == OUTPUT_RCS'.
  432. X    (diff_2_files) [OUTPUT_RCS]: Suppress the "File X missing
  433. X    newline" message.
  434. X    (build_script) [OUTPUT_RCS]: Cause the last line to compare as
  435. X    different if exactly one of the files is missing its final
  436. X    newline.
  437. X
  438. X    * io.c (find_and_hash_each_line): Bug fix in
  439. X    ignore_space_change mode.  Change line's length to include the
  440. X    newline.  For OUTPUT_RCS, decrement last line's length if
  441. X    there is no final newline.
  442. X    (find_identical_ends) [OUTPUT_RCS]: If one of the files is
  443. X    missing a final newline, make sure it's not included in either
  444. X    the prefix or suffix.
  445. X
  446. X    * util.c (print_1_line): Change line output routine to account
  447. X    for line length including the newline.
  448. X
  449. XTue Jun 27 02:35:28 1989  Roland McGrath  (roland at hobbes.ai.mit.edu)
  450. X
  451. X    * Makefile: Inserted $(archpfx) where appropriate.
  452. X
  453. XWed May 17 20:18:43 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  454. X
  455. X    * diff3.c [USG]: Include fcntl.h.
  456. X
  457. X    * diff.h [USG]: New compilation flags HAVE_NDIR, HAVE_DIRECT.
  458. X
  459. XWed Apr 26 15:35:57 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  460. X
  461. X    * dir.c (diff_dirs): Two new args, NONEX1 and NONEX2, say to pretend
  462. X    nonex dirs are empty.
  463. X    (dir_sort): New arg NONEX, likewise.
  464. X    * diff.c (compare_files): Pass those args.
  465. X    Sometimes call diff_dirs if subdir exists in just one place.
  466. X
  467. XWed Apr 12 01:10:27 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  468. X
  469. X    * io.c (find_identical_ends): Set END0 *after* last char
  470. X    during backward scan for suffix.
  471. X
  472. XSat Apr  8 15:49:49 1989  Randall Smith  (randy at apple-gunkies.ai.mit.edu)
  473. X
  474. X    * diff3.c (using_to_diff3_block): Now find high marks in files 1
  475. X    and 2 through mapping off of the last difference instead of the
  476. X    first.
  477. X
  478. X    * diff3.c: Many trivial changes to spelling inside comments. 
  479. X
  480. XFri Feb 24 12:38:03 1989  Randall Smith  (randy at gluteus.ai.mit.edu)
  481. X
  482. X    * util.c, normal.c, io.c, ed.c, dir.c, diff.h, diff.c, context.c,
  483. X    analyze.c, Makefile: Changed copyright header to conform with new
  484. X    GNU General Public license.
  485. X    * diff3.c: Changed copyright header to conform with new GNU
  486. X    General Public license.
  487. X    * COPYING: Made a hard link to /gp/rms/COPYING.
  488. X
  489. XFri Feb 24 10:01:58 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  490. X
  491. X    * io.c (slurp): Leave 2 chars space at end of buffer, not one.
  492. X    (find_identical_ends): Special case if either file is empty;
  493. X    don't try to make a sentinel since could crash.
  494. X
  495. XWed Feb 15 14:24:48 1989  Jay Fenlason  (hack at apple-gunkies.ai.mit.edu)
  496. X
  497. X    * diff3.c (message)  Re-wrote routine to avoid using alloca()
  498. X
  499. XWed Feb 15 06:19:14 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  500. X
  501. X    * io.c (find_identical_ends): Delete the variable `bytes'.
  502. X
  503. XSun Feb 12 11:50:36 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  504. X
  505. X    * io.c (slurp): ->bufsize is nominal amount we have room for;
  506. X    add room for sentinel when calling xmalloc or xrealloc.
  507. X
  508. X    * io.c (find_identical_ends): Do need overrun check in finding suffix.
  509. X
  510. XFri Feb 10 01:28:15 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  511. X
  512. X    * diff.c (main): -C now takes arg to specify context length.
  513. X    Now -p to show C function name--Damned IEEE!
  514. X    Fatal error if context length spec'd twice.
  515. X
  516. X    * ed.c (print_ed_hunk): Now special treatment only for lines containing
  517. X    precisely a dot and nothing else.  Output `..', end the insert,
  518. X    substitute that one line, then resume the insert if nec.
  519. X
  520. X    * io.c (find_and_hash_lines): When backing up over starting context,
  521. X    don't move past buffer-beg.
  522. X
  523. X    * io.c (find_identical_ends): Use sentinels to make the loops faster.
  524. X    If files are identical, skip the 2nd loop and return quickly.
  525. X    (slurp): Leave 1 char extra space after each buffer.
  526. X
  527. X    * analyze.c (diff_2_files): Mention difference in final newlines.
  528. X
  529. XWed Jan 25 22:44:44 1989  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  530. X
  531. X    * dir.c (diff_dirs): Use * when calling fcn ptr variable.
  532. X
  533. XSat Dec 17 14:12:06 1988  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  534. X
  535. X    * Makefile: New vars INSTALL and LIBS used in some rules;
  536. X    provide default defns plus commented-put defns for sysV.
  537. X
  538. XThu Nov 17 16:42:53 1988  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  539. X
  540. X    * dir.c (dir_sort): Open-trouble not fatal; just say # files is -1.
  541. X    (diff_dirs): If dir_sort does that, give up and return 2.
  542. X
  543. X    * diff.c (compare_files): Don't open directories.
  544. X    Don't close them specially either.
  545. X    Cross-propagate inf[i].dir_p sooner.
  546. X
  547. XSun Nov 13 11:19:36 1988  Richard Stallman  (rms at sugar-bombs.ai.mit.edu)
  548. X
  549. X    * diff.h: Declare index, rindex.
  550. X
  551. X    * diff.c (compare_files): If comparing foodir with b/f,
  552. X    use foodir/f, not foodir/b/f.
  553. X
  554. X    * diff.c (compare_files): Don't print "are identical" msg for 2 dirs.
  555. X    Status now 1 if one file is a dir and the other isn't, etc.
  556. X
  557. XThu Nov  3 16:30:24 1988  Randall Smith  (randy at gluteus.ai.mit.edu)
  558. X
  559. X    * Makefile: Added a define for diff3 to define DIFF_PROGRAM.
  560. X
  561. X    * util.c: Added hack to make sure that perror was not called with
  562. X    a null pointer.
  563. X
  564. X    * diff.c: Changed S_IFDIR to S_IFMT in masking type of file bits
  565. X    out. 
  566. X
  567. X    * diff3.c: Included USG compatibility defines.
  568. X
  569. X    * diff.h: Moved sys/file.h into #else USG section (not needed or
  570. X    wanted on System V).
  571. X
  572. X    * ed.c, analyze.c, context.c: Shortened names to 12 characters for
  573. X    the sake of System V (too simple not to do).
  574. X
  575. XLocal Variables:
  576. Xmode: indented-text
  577. Xleft-margin: 8
  578. Xversion-control: never
  579. XEnd:
  580. END_OF_FILE
  581. if test 19300 -ne `wc -c <'ChangeLog'`; then
  582.     echo shar: \"'ChangeLog'\" unpacked with wrong size!
  583. fi
  584. # end of 'ChangeLog'
  585. fi
  586. if test -f 'io.c' -a "${1}" != "-c" ; then 
  587.   echo shar: Will not clobber existing file \"'io.c'\"
  588. else
  589. echo shar: Extracting \"'io.c'\" \(18072 characters\)
  590. sed "s/^X//" >'io.c' <<'END_OF_FILE'
  591. X/* File I/O for GNU DIFF.
  592. X   Copyright (C) 1988, 1989 Free Software Foundation, Inc.
  593. X
  594. XThis file is part of GNU DIFF.
  595. X
  596. XGNU DIFF is free software; you can redistribute it and/or modify
  597. Xit under the terms of the GNU General Public License as published by
  598. Xthe Free Software Foundation; either version 1, or (at your option)
  599. Xany later version.
  600. X
  601. XGNU DIFF is distributed in the hope that it will be useful,
  602. Xbut WITHOUT ANY WARRANTY; without even the implied warranty of
  603. XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  604. XGNU General Public License for more details.
  605. X
  606. XYou should have received a copy of the GNU General Public License
  607. Xalong with GNU DIFF; see the file COPYING.  If not, write to
  608. Xthe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  609. X
  610. X#include "diff.h"
  611. X
  612. X/* Rotate a value n bits to the left. */
  613. X#define UINT_BIT (sizeof (unsigned) * CHAR_BIT)
  614. X#define ROL(v, n) ((v) << (n) | (v) >> UINT_BIT - (n))
  615. X
  616. X/* Given a hash value and a new character, return a new hash value. */
  617. X#define HASH(h, c) ((c) + ROL (h, 7))
  618. X
  619. X/* Current file under consideration. */
  620. Xstruct file_data *current;
  621. X
  622. X/* Check for binary files and compare them for exact identity.  */
  623. X
  624. X/* Return 1 if BUF contains a non text character.
  625. X   SIZE is the number of characters in BUF.  */
  626. X
  627. Xstatic int
  628. Xbinary_file_p (buf, size)
  629. X     char *buf;
  630. X     int size;
  631. X{
  632. X  static const char textchar[] = {
  633. X    /* ISO 8859 */
  634. X    0, 0, 0, 0, 0, 0, 0, 0,
  635. X    0, 1, 1, 1, 1, 1, 0, 0,
  636. X    0, 0, 0, 0, 0, 0, 0, 0,
  637. X    0, 0, 0, 0, 0, 0, 0, 0,
  638. X    1, 1, 1, 1, 1, 1, 1, 1,
  639. X    1, 1, 1, 1, 1, 1, 1, 1,
  640. X    1, 1, 1, 1, 1, 1, 1, 1,
  641. X    1, 1, 1, 1, 1, 1, 1, 1,
  642. X    1, 1, 1, 1, 1, 1, 1, 1,
  643. X    1, 1, 1, 1, 1, 1, 1, 1,
  644. X    1, 1, 1, 1, 1, 1, 1, 1,
  645. X    1, 1, 1, 1, 1, 1, 1, 1,
  646. X    1, 1, 1, 1, 1, 1, 1, 1,
  647. X    1, 1, 1, 1, 1, 1, 1, 1,
  648. X    1, 1, 1, 1, 1, 1, 1, 1,
  649. X    1, 1, 1, 1, 1, 1, 1, 0,
  650. X    0, 0, 0, 0, 0, 0, 0, 0,
  651. X    0, 0, 0, 0, 0, 0, 0, 0,
  652. X    0, 0, 0, 0, 0, 0, 0, 0,
  653. X    0, 0, 0, 0, 0, 0, 0, 0,
  654. X    1, 1, 1, 1, 1, 1, 1, 1,
  655. X    1, 1, 1, 1, 1, 1, 1, 1,
  656. X    1, 1, 1, 1, 1, 1, 1, 1,
  657. X    1, 1, 1, 1, 1, 1, 1, 1,
  658. X    1, 1, 1, 1, 1, 1, 1, 1,
  659. X    1, 1, 1, 1, 1, 1, 1, 1,
  660. X    1, 1, 1, 1, 1, 1, 1, 1,
  661. X    1, 1, 1, 1, 1, 1, 1, 1,
  662. X    1, 1, 1, 1, 1, 1, 1, 1,
  663. X    1, 1, 1, 1, 1, 1, 1, 1,
  664. X    1, 1, 1, 1, 1, 1, 1, 1,
  665. X    1, 1, 1, 1, 1, 1, 1, 1,
  666. X  };
  667. X  while (--size >= 0)
  668. X    if (!textchar[*buf++ & 0377])
  669. X      return 1;
  670. X  return 0;
  671. X}
  672. X
  673. Xint binary_file_threshold = 512;
  674. X
  675. X/* Slurp the current file completely into core.
  676. X   Return nonzero if it appears to be a binary file.  */
  677. X
  678. Xstatic int
  679. Xslurp ()
  680. X{
  681. X  /* If we have a nonexistent file at this stage, treat it as empty.  */
  682. X  if (current->desc < 0)
  683. X    {
  684. X      current->bufsize = 0;
  685. X      current->buffered_chars = 0;
  686. X      current->buffer = 0;
  687. X    }
  688. X  /* If it's a regular file, we can just get the size out of the stat
  689. X     block and slurp it in all at once. */
  690. X  /* In all cases, we leave room in the buffer for 2 extra chars
  691. X     beyond those that current->bufsize describes:
  692. X     one for a newline (in case the text does not end with one)
  693. X     and one for a sentinel in find_identical_ends.  */
  694. X  else if ((current->stat.st_mode & S_IFMT) == S_IFREG)
  695. X    {
  696. X      current->bufsize = current->stat.st_size;
  697. X      current->buffer = (char *) xmalloc (current->bufsize + 2);
  698. X      current->buffered_chars
  699. X    = read (current->desc, current->buffer, current->bufsize);
  700. X      if (current->buffered_chars < 0)
  701. X    pfatal_with_name (current->name);
  702. X    }
  703. X  else
  704. X    {
  705. X      int cc;
  706. X
  707. X      current->bufsize = 4096;
  708. X      current->buffer = (char *) xmalloc (current->bufsize + 2);
  709. X      current->buffered_chars = 0;
  710. X      
  711. X      /* Not a regular file; read it in a little at a time, growing the
  712. X     buffer as necessary. */
  713. X      while ((cc = read (current->desc,
  714. X             current->buffer + current->buffered_chars,
  715. X             current->bufsize - current->buffered_chars))
  716. X         > 0)
  717. X    {
  718. X      current->buffered_chars += cc;
  719. X      if (current->buffered_chars == current->bufsize)
  720. X        {
  721. X          current->bufsize = current->bufsize * 2;
  722. X          current->buffer = (char *) xrealloc (current->buffer,
  723. X                           current->bufsize + 2);
  724. X        }
  725. X    }
  726. X      if (cc < 0)
  727. X    pfatal_with_name (current->name);
  728. X    }
  729. X  
  730. X  /* Check first part of file to see if it's a binary file.  */
  731. X  if (! always_text_flag
  732. X      && binary_file_p (current->buffer,
  733. X            min (current->buffered_chars, binary_file_threshold)))
  734. X    return 1;
  735. X
  736. X  /* If not binary, make sure text ends in a newline,
  737. X     but remember that we had to add one unless -B is in effect.  */
  738. X  if (current->buffered_chars > 0
  739. X      && current->buffer[current->buffered_chars - 1] != '\n')
  740. X    {
  741. X      current->missing_newline = !ignore_blank_lines_flag;
  742. X      current->buffer[current->buffered_chars++] = '\n';
  743. X    }
  744. X  else
  745. X    current->missing_newline = 0;
  746. X
  747. X  /* Don't use uninitialized storage. */
  748. X  if (current->buffer != 0)
  749. X    current->buffer[current->buffered_chars] = '\0';
  750. X
  751. X  return 0;
  752. X}
  753. X
  754. X/* Split the file into lines, simultaneously computing the hash codes for
  755. X   each line. */
  756. X
  757. Xvoid
  758. Xfind_and_hash_each_line ()
  759. X{
  760. X  unsigned h;
  761. X  int i;
  762. X  unsigned char *p = (unsigned char *) current->prefix_end, *ip, c;
  763. X
  764. X  /* Attempt to get a good initial guess as to the number of lines. */
  765. X  current->linbufsize = current->buffered_chars / 50 + 5;
  766. X  current->linbuf
  767. X    = (struct line_def *) xmalloc (current->linbufsize * sizeof (struct line_def));
  768. X
  769. X  if (function_regexp || output_style == OUTPUT_IFDEF)
  770. X    {
  771. X      /* If the -C, -D or -F option is used, we need to find the lines
  772. X     of the matching prefix.  At least we will need to find the last few,
  773. X     but since we don't know how many, it's easiest to find them all.
  774. X     If -D is specified, we need all the lines of the first file.  */
  775. X      current->buffered_lines = 0;
  776. X      p = (unsigned char *) current->buffer;
  777. X    }
  778. X  else
  779. X    {
  780. X      /* Skip the identical prefixes, except be prepared to handle context.
  781. X     In fact, handle 1 more preceding line than the context says,
  782. X     in case shift_boundaries moves things backwards in this file.  */
  783. X      current->buffered_lines = current->prefix_lines - context - 1;
  784. X      if (current->buffered_lines < 0)
  785. X    current->buffered_lines = 0;
  786. X      for (i = 0; i < context + 1; ++i)
  787. X    /* Unless we are at the beginning, */
  788. X    if ((char *) p != current->buffer)
  789. X      /* Back up at least 1 char until at the start of a line.  */
  790. X      while ((char *) --p != current->buffer && p[-1] != '\n')
  791. X        ;
  792. X    }
  793. X
  794. X  while ((char *) p < current->suffix_begin)
  795. X    {
  796. X      h = 0;
  797. X      ip = p;
  798. X
  799. X      if (current->prefix_end <= (char *) p)
  800. X    {
  801. X      /* Hash this line until we find a newline. */
  802. X      if (ignore_case_flag)
  803. X        {
  804. X          if (ignore_all_space_flag)
  805. X        while ((c = *p) != '\n')
  806. X          {
  807. X            if (! isspace (c))
  808. X              if (isupper (c))
  809. X            h = HASH (h, tolower (c));
  810. X              else
  811. X            h = HASH (h, c);
  812. X            ++p;
  813. X          }
  814. X          else if (ignore_space_change_flag)
  815. X
  816. X        while ((c = *p) != '\n')
  817. X          {
  818. X            if (c == ' ' || c == '\t')
  819. X              {
  820. X            while ((c = *p) == ' ' || c == '\t')
  821. X              ++p;
  822. X            if (c == '\n')
  823. X              break;
  824. X            h = HASH (h, ' ');
  825. X              }
  826. X            /* C is now the first non-space.  */
  827. X            if (isupper (c))
  828. X              h = HASH (h, tolower (c));
  829. X            else
  830. X              h = HASH (h, c);
  831. X            ++p;
  832. X          }
  833. X          else
  834. X        while ((c = *p) != '\n')
  835. X          {
  836. X            if (isupper (c))
  837. X              h = HASH (h, tolower (c));
  838. X            else
  839. X              h = HASH (h, c);
  840. X            ++p;
  841. X          }
  842. X        }
  843. X      else
  844. X        {
  845. X          if (ignore_all_space_flag)
  846. X        while ((c = *p) != '\n')
  847. X          {
  848. X            if (! isspace (c))
  849. X              h = HASH (h, c);
  850. X            ++p;
  851. X          }
  852. X          else if (ignore_space_change_flag)
  853. X        while ((c = *p) != '\n')
  854. X          {
  855. X            if (c == ' ' || c == '\t')
  856. X              {
  857. X            while ((c = *p) == ' ' || c == '\t')
  858. X              ++p;
  859. X            if (c == '\n')
  860. X              break;
  861. X            h = HASH (h, ' ');
  862. X              }
  863. X            /* C is not the first non-space.  */
  864. X            h = HASH (h, c);
  865. X            ++p;
  866. X          }
  867. X          else
  868. X        while ((c = *p) != '\n')
  869. X          {
  870. X            h = HASH (h, c);
  871. X            ++p;
  872. X          }
  873. X        }
  874. X    }
  875. X      else
  876. X    /* This line is part of the matching prefix,
  877. X       so we don't need to hash it.  */
  878. X    while (*p != '\n')
  879. X      ++p;
  880. X      
  881. X      /* Maybe increase the size of the line table. */
  882. X      if (current->buffered_lines >= current->linbufsize)
  883. X    {
  884. X      while (current->buffered_lines >= current->linbufsize)
  885. X        current->linbufsize *= 2;
  886. X      current->linbuf
  887. X        = (struct line_def *) xrealloc (current->linbuf,
  888. X                        current->linbufsize
  889. X                        * sizeof (struct line_def));
  890. X    }
  891. X      current->linbuf[current->buffered_lines].text = (char *) ip;
  892. X      current->linbuf[current->buffered_lines].length = p - ip + 1;
  893. X      current->linbuf[current->buffered_lines].hash = h;
  894. X      ++current->buffered_lines;
  895. X      ++p;
  896. X    }
  897. X
  898. X  i = 0;
  899. X  while ((i < context || output_style == OUTPUT_IFDEF)
  900. X     && (char *) p < current->buffer + current->buffered_chars)
  901. X    {
  902. X      ip = p;
  903. X      while (*p++ != '\n')
  904. X    ;
  905. X      /* Maybe increase the size of the line table. */
  906. X      if (current->buffered_lines >= current->linbufsize)
  907. X    {
  908. X      while (current->buffered_lines >= current->linbufsize)
  909. X        current->linbufsize *= 2;
  910. X      current->linbuf
  911. X        = (struct line_def *) xrealloc (current->linbuf,
  912. X                        current->linbufsize
  913. X                        * sizeof (struct line_def));
  914. X    }
  915. X      current->linbuf[current->buffered_lines].text = (char *) ip;
  916. X      current->linbuf[current->buffered_lines].length = p - ip;
  917. X      current->linbuf[current->buffered_lines].hash = 0;
  918. X      ++current->buffered_lines;
  919. X      ++i;
  920. X    }
  921. X
  922. X  if (ROBUST_OUTPUT_STYLE (output_style)
  923. X      && current->missing_newline
  924. X      && current->suffix_begin == current->buffer + current->buffered_chars)
  925. X    --current->linbuf[current->buffered_lines - 1].length;
  926. X}
  927. X
  928. X/* Given a vector of two file_data objects, find the identical
  929. X   prefixes and suffixes of each object. */
  930. X
  931. Xstatic void
  932. Xfind_identical_ends (filevec)
  933. X     struct file_data filevec[];
  934. X{
  935. X  char *p0, *p1, *end0, *beg0;
  936. X  int lines;
  937. X
  938. X  if (filevec[0].buffered_chars == 0 || filevec[1].buffered_chars == 0)
  939. X    {
  940. X      filevec[0].prefix_end = filevec[0].buffer;
  941. X      filevec[1].prefix_end = filevec[1].buffer;
  942. X      filevec[0].prefix_lines = filevec[1].prefix_lines = 0;
  943. X      filevec[0].suffix_begin = filevec[0].buffer + filevec[0].buffered_chars;
  944. X      filevec[1].suffix_begin = filevec[1].buffer + filevec[1].buffered_chars;
  945. X      filevec[0].suffix_lines = filevec[1].suffix_lines = 0;
  946. X      return;
  947. X    }
  948. X
  949. X  /* Find identical prefix.  */
  950. X
  951. X  p0 = filevec[0].buffer;
  952. X  p1 = filevec[1].buffer;
  953. X  lines = 0;
  954. X
  955. X  /* Insert end "sentinels", in this case characters that are guaranteed
  956. X     to make the equality test false, and thus terminate the loop.  */
  957. X
  958. X  if (filevec[0].buffered_chars < filevec[1].buffered_chars)
  959. X    p0[filevec[0].buffered_chars] = ~p1[filevec[0].buffered_chars];
  960. X  else
  961. X    p1[filevec[1].buffered_chars] = ~p0[filevec[1].buffered_chars];
  962. X
  963. X  /* Loop until first mismatch, or to the sentinel characters.  */
  964. X  while (1)
  965. X    {
  966. X      char c = *p0++;
  967. X      if (c != *p1++)
  968. X    break;
  969. X      if (c == '\n')
  970. X    ++lines;
  971. X    }
  972. X
  973. X  /* Don't count missing newline as part of prefix in RCS mode. */
  974. X  if (ROBUST_OUTPUT_STYLE (output_style)
  975. X      && ((filevec[0].missing_newline
  976. X       && p0 - filevec[0].buffer > filevec[0].buffered_chars)
  977. X      ||
  978. X      (filevec[1].missing_newline
  979. X       && p1 - filevec[1].buffer > filevec[1].buffered_chars)))
  980. X    --p0, --p1, --lines;
  981. X
  982. X  /* If the sentinel was passed, and lengths are equal, the
  983. X     files are identical.  */
  984. X  if (p0 - filevec[0].buffer > filevec[0].buffered_chars
  985. X      && filevec[0].buffered_chars == filevec[1].buffered_chars)
  986. X    {
  987. X      filevec[0].prefix_end = p0 - 1;
  988. X      filevec[1].prefix_end = p1 - 1;
  989. X      filevec[0].prefix_lines = filevec[1].prefix_lines = lines;
  990. X      filevec[0].suffix_begin = filevec[0].buffer;
  991. X      filevec[1].suffix_begin = filevec[1].buffer;
  992. X      filevec[0].suffix_lines = filevec[1].suffix_lines = lines;
  993. X      return;
  994. X    }
  995. X
  996. X  /* Point at first nonmatching characters.  */
  997. X  --p0, --p1;
  998. X
  999. X  /* Skip back to last line-beginning in the prefix.  */
  1000. X  while (p0 != filevec[0].buffer && p0[-1] != '\n')
  1001. X    --p0, --p1;
  1002. X
  1003. X  /* Record the prefix.  */
  1004. X  filevec[0].prefix_end = p0;
  1005. X  filevec[1].prefix_end = p1;
  1006. X  filevec[0].prefix_lines = filevec[1].prefix_lines = lines;
  1007. X  
  1008. X  /* Find identical suffix.  */
  1009. X
  1010. X  /* P0 and P1 point beyond the last chars not yet compared.  */
  1011. X  p0 = filevec[0].buffer + filevec[0].buffered_chars;
  1012. X  p1 = filevec[1].buffer + filevec[1].buffered_chars;
  1013. X  lines = 0;
  1014. X
  1015. X  if (! ROBUST_OUTPUT_STYLE (output_style)
  1016. X      || filevec[0].missing_newline == filevec[1].missing_newline)
  1017. X    {
  1018. X      end0 = p0;        /* Addr of last char in file 0.  */
  1019. X
  1020. X      /* Get value of P0 at which we should stop scanning backward:
  1021. X     this is when either P0 or P1 points just past the last char
  1022. X     of the identical prefix.  */
  1023. X      if (filevec[0].buffered_chars < filevec[1].buffered_chars)
  1024. X    beg0 = filevec[0].prefix_end;
  1025. X      else
  1026. X    /* Figure out where P0 will be when P1 is at the end of the prefix.
  1027. X       Thus we only need to test P0.  */
  1028. X    beg0 = (filevec[0].prefix_end
  1029. X        + filevec[0].buffered_chars - filevec[1].buffered_chars);
  1030. X
  1031. X      /* Scan back until chars don't match or we reach that point.  */
  1032. X      while (p0 != beg0)
  1033. X    {
  1034. X      char c = *--p0;
  1035. X      if (c != *--p1)
  1036. X        {
  1037. X          /* Point at the first char of the matching suffix.  */
  1038. X          ++p0, ++p1;
  1039. X          break;
  1040. X        }
  1041. X      if (c == '\n')
  1042. X        ++lines;
  1043. X    }
  1044. X
  1045. X      /* Are we at a line-beginning in both files?  */
  1046. X      if (p0 != end0
  1047. X      && !((p0 == filevec[0].buffer || p0[-1] == '\n')
  1048. X           &&
  1049. X           (p1 == filevec[1].buffer || p1[-1] == '\n')))
  1050. X    {
  1051. X      /* No.  We counted one line too many.  */
  1052. X      --lines;
  1053. X      /* Advance to next place that is a line-beginning in both files.  */
  1054. X      do
  1055. X        {
  1056. X          ++p0, ++p1;
  1057. X        }
  1058. X      while (p0 != end0 && p0[-1] != '\n');
  1059. X    }
  1060. X    }
  1061. X
  1062. X  /* Record the suffix.  */
  1063. X  filevec[0].suffix_begin = p0;
  1064. X  filevec[1].suffix_begin = p1;
  1065. X  filevec[0].suffix_lines = filevec[1].suffix_lines = lines;
  1066. X}
  1067. X
  1068. X/* Lines are put into equivalence classes (of lines that match in line_cmp).
  1069. X   Each equivalence class is represented by one of these structures,
  1070. X   but only while the classes are being computed.
  1071. X   Afterward, each class is represented by a number.  */
  1072. Xstruct equivclass
  1073. X{
  1074. X  struct equivclass *next;    /* Next item in this bucket. */
  1075. X  struct line_def line;    /* A line that fits this class. */
  1076. X};
  1077. X
  1078. X/* Hash-table: array of buckets, each being a chain of equivalence classes.  */
  1079. Xstatic struct equivclass **buckets;
  1080. X  
  1081. X/* Size of the bucket array. */
  1082. Xstatic int nbuckets;
  1083. X
  1084. X/* Array in which the equivalence classes are allocated.
  1085. X   The bucket-chains go through the elements in this array.
  1086. X   The number of an equivalence class is its index in this array.  */
  1087. Xstatic struct equivclass *equivs;
  1088. X
  1089. X/* Index of first free element in the array `equivs'.  */
  1090. Xstatic int equivs_index;
  1091. X
  1092. X/* Size allocated to the array `equivs'.  */
  1093. Xstatic int equivs_alloc;
  1094. X
  1095. X/* Largest primes less than some power of two, for nbuckets.  Values range
  1096. X   from useful to preposterous.  If one of these numbers isn't prime
  1097. X   after all, don't blame it on me, blame it on primes (6) . . . */
  1098. Xstatic int primes[] =
  1099. X{
  1100. X  509,
  1101. X  1021,
  1102. X  2039,
  1103. X  4093,
  1104. X  8191,
  1105. X  16381,
  1106. X  32749,
  1107. X  65521,
  1108. X  131071,
  1109. X  262139,
  1110. X  524287,
  1111. X  1048573,
  1112. X  2097143,
  1113. X  4194301,
  1114. X  8388593,
  1115. X  16777213,
  1116. X  33554393,
  1117. X  67108859,            /* Preposterously large . . . */
  1118. X  -1
  1119. X};
  1120. X
  1121. X/* Index of current nbuckets in primes. */
  1122. Xstatic int primes_index;
  1123. X
  1124. X/* Find the equiv class associated with line N of the current file.  */
  1125. X
  1126. Xstatic int
  1127. Xfind_equiv_class (n)
  1128. X     int n;
  1129. X{
  1130. X  int bucket;
  1131. X  struct equivclass *b, *p = NULL;
  1132. X
  1133. X  /* Equivalence class 0 is permanently allocated to lines that were
  1134. X     not hashed because they were parts of identical prefixes or
  1135. X     suffixes. */
  1136. X  if (n < current->prefix_lines
  1137. X      || current->linbuf[n].text >= current->suffix_begin)
  1138. X    return 0;
  1139. X
  1140. X  /* Check through the appropriate bucket to see if there isn't already
  1141. X     an equivalence class for this line. */
  1142. X  bucket = current->linbuf[n].hash % nbuckets;
  1143. X  b = buckets[bucket];
  1144. X  while (b)
  1145. X    {
  1146. X      if (b->line.hash == current->linbuf[n].hash
  1147. X      && (b->line.length == current->linbuf[n].length
  1148. X          /* Lines of different lengths can match with certain options.  */
  1149. X          || length_varies)
  1150. X      && !line_cmp (&b->line, ¤t->linbuf[n]))
  1151. X    return b - equivs;
  1152. X      p = b, b = b->next;
  1153. X    }
  1154. X
  1155. X  /* Create a new equivalence class in this bucket. */
  1156. X
  1157. X  p = &equivs[equivs_index++];
  1158. X  p->next = buckets[bucket];
  1159. X  buckets[bucket] = p;
  1160. X  p->line = current->linbuf[n];
  1161. X
  1162. X  return equivs_index - 1;
  1163. X}
  1164. X
  1165. X/* Given a vector of two file_data objects, read the file associated
  1166. X   with each one, and build the table of equivalence classes.
  1167. X   Return nonzero if either file appears to be a binary file.  */
  1168. X
  1169. Xint
  1170. Xread_files (filevec)
  1171. X     struct file_data filevec[];
  1172. X{
  1173. X  int i, j;
  1174. X  int binary = 0;
  1175. X  int this_binary;
  1176. X
  1177. X  current = &filevec[0];
  1178. X  binary = this_binary = slurp ();
  1179. X
  1180. X  current = &filevec[1];
  1181. X  this_binary = slurp ();
  1182. X  if (binary || this_binary)
  1183. X    return 1;
  1184. X
  1185. X  find_identical_ends (filevec);
  1186. X
  1187. X  for (i = 0; i < 2; ++i)
  1188. X    {
  1189. X      current = &filevec[i];
  1190. X      find_and_hash_each_line ();
  1191. X    }
  1192. X
  1193. X  /* This is guaranteed to be enough space.  */
  1194. X  equivs_alloc = filevec[0].buffered_lines + filevec[1].buffered_lines + 1;
  1195. X  equivs = (struct equivclass *) xmalloc (equivs_alloc * sizeof (struct equivclass));
  1196. X  /* Equivalence class 0 is permanently safe for lines that were not
  1197. X     hashed.  Real equivalence classes start at 1. */
  1198. X  equivs_index = 1;
  1199. X  
  1200. X  primes_index = 0;
  1201. X  while (primes[primes_index] < equivs_alloc / 3)
  1202. X    primes_index++;
  1203. X
  1204. X  buckets = (struct equivclass **) xmalloc (primes[primes_index] * sizeof (struct equivclass *));
  1205. X  bzero (buckets, primes[primes_index] * sizeof (struct equivclass *));
  1206. X  nbuckets = primes[primes_index];
  1207. X
  1208. X  for (i = 0; i < 2; ++i)
  1209. X    {
  1210. X      current = &filevec[i];
  1211. X      current->equivs
  1212. X    = (int *) xmalloc (current->buffered_lines * sizeof (int));
  1213. X      for (j = 0; j < current->buffered_lines; ++j)
  1214. X    current->equivs[j] = find_equiv_class (j);
  1215. X    }
  1216. X
  1217. X  filevec[0].equiv_max = filevec[1].equiv_max = equivs_index;
  1218. X
  1219. X  free (equivs);
  1220. X  free (buckets);
  1221. X
  1222. X  return 0;
  1223. X}
  1224. END_OF_FILE
  1225. if test 18072 -ne `wc -c <'io.c'`; then
  1226.     echo shar: \"'io.c'\" unpacked with wrong size!
  1227. fi
  1228. # end of 'io.c'
  1229. fi
  1230. echo shar: End of archive 4 \(of 8\).
  1231. cp /dev/null ark4isdone
  1232. MISSING=""
  1233. for I in 1 2 3 4 5 6 7 8 ; do
  1234.     if test ! -f ark${I}isdone ; then
  1235.     MISSING="${MISSING} ${I}"
  1236.     fi
  1237. done
  1238. if test "${MISSING}" = "" ; then
  1239.     echo You have unpacked all 8 archives.
  1240.     rm -f ark[1-9]isdone
  1241. else
  1242.     echo You still need to unpack the following archives:
  1243.     echo "        " ${MISSING}
  1244. fi
  1245. ##  End of shell archive.
  1246. exit 0
  1247.  
  1248. exit 0 # Just in case...
  1249.